﻿using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using Gp.Scripts.Core;
using Gp.Scripts.Equip;
using Helpers;
using TMPro;
using UnityEngine;
using Object = UnityEngine.Object;

namespace Gp.Scripts.GUI
{
    public class WidgetMain_NodeSkill : WidgetMain_NodeSkillBase
    {
        // [SerializeField] private BaseSkillButton buttonPrefab;
        // [SerializeField] private Transform abilityParent;
        // [SerializeField] private Transform weaponParent;
        // [SerializeField] private Transform magicParent;

        // [SerializeField] private SkillExecutionZone executionZone;
        // [SerializeField] private SkillToolTipsController toolTipsController;


        private Animator _animator;

        private readonly List<BaseSkillButton> _buttons = new();
        private readonly List<BaseSkillButton> _weaponButtons = new();

        private static readonly int Execution = Animator.StringToHash("Execution");
        private BaseUnit _currentUnit;

        protected override void OnInternalCreated()
        {
            _animator = this.GetComponent<Animator>();
            EventHandler.RegisterEvent<Event_Unit.Select>(UpdateSkillSlot);
            EventHandler.RegisterEvent<Event_Unit.Deselect>(Clear);
            EventHandler.RegisterEvent<Event_Unit.CostChange>(e => UpdateResource(e.Unit));
            EventHandler.RegisterEvent<Event_BattleEnd>(_ => Clear());
            EventHandler.RegisterEvent<Event_SkillUI.Display>(OnAbilityChange);
            EventHandler.RegisterEvent<Event_SkillUI.Cancel>(CancelSkill);
            EventHandler.RegisterEvent<WeaponChangeEvent>(OnWeaponChange);
        }

        private void CancelSkill(Event_SkillUI.Cancel obj)
        {
            this.ClearZone();
        }


        private void OnWeaponChange(WeaponChangeEvent obj)
        {
            if (obj.ComEquip.Unit != _currentUnit) return;
        }


        private void OnAbilityChange(Event_SkillUI.Display args)
        {
            // var unit = args.SkillEntity.UnitReference;
            this.mExecute_SkillExecutionZone.OnShow(args.SkillEntity);
            _animator.SetBool(Execution, true);
        }


        private void ClearZone()
        {
            _animator.SetBool(Execution, false);
            this.mExecute_SkillExecutionZone.ClearUp();
        }


        private void Clear(Event_Unit.Deselect obj)
        {
            Clear();
        }


        private void UpdateSkillSlot(Event_Unit.Select e)
        {
            if (!e.Unit && !ObjectHelper.IsPlayer(e.Unit.gameObject)) return;
            _currentUnit = e.Unit;

            List<SkillEntity> abilities = new List<SkillEntity>();
            abilities.AddRange(e.Unit.ComSkill.AbilitySkill);

            foreach (var item in abilities)
            {
                if (item is IPassiveAbility) continue;
                var button = Object.Instantiate(mSkillButtonPrefab_BoxSkillButton, mPartAbility_RectTransform, false);
                button.gameObject.SetActive(false);
                button.Init(item, null);
                _buttons.Add(button);
            }

            // 更新行动点
            UpdateResource(e.Unit);
        }

        private void UpdateResource(BaseUnit unit)
        {
            var txt = this.mResource_RectTransform.Find("Container/Action Point/Thumb Object/Text (TMP)");
            txt.GetComponent<TMP_Text>()
                .SetText(Helpers.BattleHelper.GetTimeCostString(unit.ComCost[CostField.ActionTime]));
        }


        private void UpdateWeaponSkill(WeaponEntity weapon)
        {
            if (_currentUnit == null) return;

            foreach (var b in _weaponButtons.Select(b => b.gameObject))
            {
                Object.Destroy(b);
            }

            _weaponButtons.Clear();

            foreach (var p in _currentUnit.ComSkill.WeaponAbilities)
            {
                if (p.Weapon != weapon) continue;
                var button = Object.Instantiate(this.mSkillButtonPrefab_BoxSkillButton,
                    this.mPartWeapon_RectTransform.transform, false);
                button.gameObject.SetActive(false);
                button.Init(p, null);
                _weaponButtons.Add(button);
            }
        }


        private void Clear()
        {
            foreach (var o in _buttons.Select(bottom => bottom.gameObject))
            {
                Object.Destroy(o);
            }

            foreach (var b in _weaponButtons.Select(b => b.gameObject))
            {
                Object.Destroy(b);
            }

            _currentUnit = null;
            ClearZone();
            _weaponButtons.Clear();
            _buttons.Clear();
        }
    }
}